package com.shawn.server.service;

import cn.hutool.core.collection.CollUtil;
import com.shawn.dubbo.api.ExaminationSoulApi;
import com.shawn.dubbo.api.QuestionnaireApi;
import com.shawn.dubbo.api.UserInfoApi;
import com.shawn.model.dto.Answer;
import com.shawn.model.entity.*;
import com.shawn.model.mongo.Report;
import com.shawn.model.vo.QuestionnaireVo;
import com.shawn.model.vo.SoulQuestionVo;
import com.shawn.model.vo.SoulResultVo;
import com.shawn.server.interceptor.ThreadContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author shawn
 * @date 2022年 11月 12日 16:30
 */

@Slf4j
@Service
public class QuestionnaireService {

    @DubboReference
    private QuestionnaireApi api;
    @DubboReference
    private ExaminationSoulApi soulApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    /**
     * 得到问卷
     *
     * @return {@link List}<{@link QuestionnaireVo}>
     */
    public List<QuestionnaireVo> getQuestionnaire() {
        Long userId = ThreadContext.getUserId();
        //获取查询所有问卷
        List<Questionnaire> list = api.getQuestionnaire();

        List<Long> ids = list.stream().map(Questionnaire::getId).collect(Collectors.toList());
        //根据问卷id获取问卷的问题
        Map<Long, List<SoulQuestionVo>> questionsMap = api.getSoulQuestions(ids);
        //查询用户不同问卷的最新测试表 判断当前用户是否已做过该测试,并返回最新报告id
        List<UserTest> tests = api.getUserTests(userId);
        Map<Long, UserTest> testMap = CollUtil.fieldValueMap(tests, "qid");
        //遍历所有问卷

        return list.stream().map((qu) -> {
            QuestionnaireVo vo = new QuestionnaireVo();
            BeanUtils.copyProperties(qu,vo);
            vo.setId(qu.getId().toString());
            vo.setQuestions(questionsMap.get(qu.getId()));
            if (qu.getId()!=1) {
                if (testMap.get(qu.getId()-1)!=null){
                    //判断用户有无测试
                    UserTest ut = testMap.get(qu.getId()-1);
                    vo.setIsLock(0);
                    vo.setReportId(ut.getReportId());
                }else {
                    vo.setIsLock(1);
                }
            }else {
                vo.setIsLock(0);
            }
            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 核算分数
     * 返回用户测试报告id
     * @return {@link String}
     */
    public String checkAnswers(List<Answer> answers) {
        //查询对应的问卷id
        Long qid = api.getQuestionnaireId(answers.get(0).getQuestionId());
        //获取所有选项id
        List<String> optionIds = answers.stream().map(Answer::getOptionId).collect(Collectors.toList());
        //获取所有选项,对应的分数
        Integer score = api.getScoreByIds(optionIds);
        //获取所有report
        List<Report> reports = soulApi.getAllReport();
        //遍历报告,获取对应报告,生成用户测试结果
        UserTest userTest = new UserTest();
        for (Report report : reports) {
            if (score>=report.getMinScore()&&score<report.getMaxScore()){
                userTest.setUserId(ThreadContext.getUserId());
                userTest.setQid(qid);
                userTest.setReportId(report.getId().toString());
                //保存或更新结果
                api.save(userTest);
                return report.getId().toHexString();
            }
        }
        return null;
    }


    public SoulResultVo ViewingResult(String id) {
       Report report = soulApi.getReportById(id);
       //查询用户测试表,查询所有与改用户测是结果相同的用户
       List<Long> usersId =  api.getSimilar(id);
       List<UserInfo> userInfos = userInfoApi.findByIds(usersId);
        return SoulResultVo.init(report,userInfos);
    }
}
